# coding=utf-8
import json
import os
import re
import sys
import time
import traceback
from pathlib import Path

import bs4
from selenium.webdriver import Chrome, ChromeOptions
from selenium.webdriver.common.by import By

from util import chrome_selenium_get_page_to_html, log, get_company_urls_from_file, cfg, save_file, data_save_format, \
    read_file_to_list
from util import save_search_for_product_html, read_file, setup

product_url, save_product_file_json_path = None, None
price = 0
moq = 0
current_path = Path().resolve()
data_abs_dir = os.path.join(current_path, cfg("data_dir"))
fix_dir = os.path.join(current_path, cfg("fix_dir"))
error_count = 0
error_urls = []


def get_search_for_product_to_html(url, key_world):
    """
    通过URL,以及关键词将搜索商品列表页面保存到文件
    :param url:
    :param key_world:
    :return:
    """
    options = ChromeOptions()
    options.add_argument('--disable-extensions')
    options.add_argument('--no-sandbox')  # run Chrome use root
    options.add_argument('--disable-setuid-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    options.add_argument('--disable-gpu')
    options.add_experimental_option('excludeSwitches', ['enable-automation'])
    options.add_argument("--start-maximized")
    options.add_experimental_option("detach", False)
    # service = ChromeService(service_args=['--log-level=INFO'], log_output=subprocess.STDOUT)
    # browser = Chrome(options=options, service=service)
    browser = Chrome(options=options, )

    if url.find("factory.html") > 0:
        url = url.rstrip("factory.html")
        url += "productlist.html"
    else:
        log.error(f"url地址错误:{url},  正确的URL示例: https://zstmwj.en.alibaba.com/factory.html")

    #  打开搜索
    # url+="""?SearchText=ball toy&scene=all"""
    log.info(f"搜索关键词: {key_world},公司商品搜索页url: {url}")
    time.sleep(1)
    browser.get(url)

    # 3 | click | css=.focused input |
    browser.find_element(By.XPATH, "(//input[@value=''])[3]").click()
    # 4 | type | css=.focused input | ball toy
    browser.find_element(By.CSS_SELECTOR, ".focused input").send_keys(key_world)
    # 5 | click | css=.next-search:nth-child(1) .next-icon |
    browser.find_element(By.CSS_SELECTOR, ".next-search:nth-child(1) .next-icon").click()

    # 获取商品列表
    html = browser.page_source
    # 保存
    save_search_for_product_html(html)
    time.sleep(2)
    browser.quit()


def get_search_for_product_from_html():
    """
    从保存商品列表html页面从提取单个商品URL,价格,MOQ
    :return:
    """
    log.info("get_search_for_product_from_html()")

    html = read_file(cfg('save_search_for_product_html_abs_path'))
    bs = bs4.BeautifulSoup(html, 'html.parser')
    # 获取几个商品
    product_count = cfg('product_count')
    product_count = int(product_count)
    product_list = bs.select(".next-row.next-row-no-padding.next-row-no-wrap.gallery-view")[:product_count]
    for product in product_list:
        price = product.find('div', class_='price').text
        # moq=product.find('div', class_='moq').text
        moq = product.find('div', class_='moq').text
        product_url = product.find('a', class_='product-image').attrs.get('href')
        if len(product_url) == 0:
            raise Exception("没有该关键词查询的商品!")
        product_url = "https:" + product_url
        log.info(f"product_url:{product_url}", )
        processing(product_url, price, moq)


def selenium_product_to_html(product_url):
    """
    https://hhines.en.alibaba.com/factory.html
    """
    log.info(f'selenium_product_to_html: -->{product_url}')
    chrome_selenium_get_page_to_html(product_url, cfg('product_detail_html_abs_psth'))


def product_to_bs4() -> [bs4]:
    log.info("商品页转换成bs4对象")
    file_path = cfg('product_detail_html_abs_psth')
    html = read_file(file_path)

    bs = bs4.BeautifulSoup(html, 'html.parser')
    return bs


def single_product_processing(single_product_bs: bs4):
    # ************************
    #  单个商品
    # ***********************
    # single_product_bs = bs.select(".J-search-card-wrapper")
    # print(single_product_bs.text)
    # url
    # product_url = single_product_bs.select(".search-card-e-slider__link")[0].get("href")
    # product_url = f"https://{product_url}"
    # print(product_url)
    try:
        product = {}
        # 商品名| 标题
        product_name = single_product_bs.select(".product-title")[0].text
        product["product_name"] = product_name

        # 公司地址
        company_url = single_product_bs.find("a", class_='company-name company-name-lite-vb')
        company_url = company_url.attrs.get('href')
        company_url = re.findall('(http.*.alibaba.com)', company_url)[0]
        product['company_url'] = company_url

        log.info(f"company_url:{company_url}")

        # 图片列表
        pic_list = single_product_bs.select(".detail-next-slick-slide.detail-next-slick-active.main-item")
        # print('len_1:',pic_list)
        pic_list_src = []
        i=0
        for pic in pic_list[1:4]:
            pic_src = pic.find("img", ).attrs.get('src')


            pic_src = pic_src.replace("100x100xz", "720x720q50")
            if str(pic).find("gif")!=-1:
                continue


            pic_list_src.append(pic_src)
            if i==3:
                break
            i+=1

        product["pic_list_src"] = pic_list_src

        product['moq'] = moq
        log.info(f"商品名称:{product_name}")

        product['price'] = price

        lead_time = single_product_bs.select(".lead-time")[0]

        lead_attr = lead_time.select("tr")

        lead_attr_nums_days_dic = {}
        # 数量
        lead_nums = lead_attr[0].select("td")[1:]
        # 交付时间(天)
        lead_time_days = lead_attr[1].select("td")[1:]

        i = 0
        for lead_num in lead_nums:
            lead_num_ = lead_num.text
            lead_attr_nums_days_dic[lead_num_] = lead_time_days[i].text
            i += 1
        product["lead_time"] = lead_attr_nums_days_dic

        customization_dict = {}

        customization_bs = single_product_bs.select(".customization")[0]

        custom_items = customization_bs.select(".custom-item")

        for custom in custom_items:
            custom_ = custom.select("span")
            custom_logo_key = custom_[0].text
            custom_logo_value = custom_[1].text
            customization_dict[custom_logo_key] = custom_logo_value

        product['customization'] = customization_dict

        attributes_dict = {}

        tb = single_product_bs.select(".structure-table")
        for t in tb:
            t = t
            previous = t.previous
            attribute_name = previous

            attributs_key_value = {}
            structure_rows = t.select(".structure-row")
            for structure_row in structure_rows:
                left = structure_row.select(".col-left")[0].text
                right = structure_row.select(".col-right")[0].text
                attributs_key_value[left] = right

            attributes_dict[previous] = attributs_key_value

        product["attributes"] = attributes_dict

        # _1600961516701.html
        product_id = re.findall(r'(_.*.html)', str(product_url))
        product_id = product_id[0]
        product_id = product_id.strip("_")
        product_id = product_id.strip(".html")


        # 详情图
        detail_pic_list=[]
        J_rich_text_description=single_product_bs.find("div",id="J-rich-text-description")
        pic_list= J_rich_text_description.select("img")
        for pic in pic_list:
            pic_url=pic.attrs.get("src")
            pic_url=str(pic_url)
            # log.info(pic_url)
            if  pic_url.find("img-placeholder.png")==-1:
                detail_pic_list.append(pic_url)

        if len(detail_pic_list)==0:
            log.error("没有找到详情图")
        else:
            detail_pic_url= detail_pic_list[0]
            detail_pic_url= "https:"+detail_pic_url
            product['detail_pic_url']=detail_pic_url
            log.info(detail_pic_list)



        # log.info(f"正则匹配:{product_id}")
        product['product_id'] = product_id
        log.info(product)
        pj = json.dumps(product, ensure_ascii=False)
        # 全局保存路径
        global save_product_file_json_path
        save_file(pj + "\n", save_product_file_json_path, 'a')
        print()
    except Exception as e:
        log.info("报错啦!!!!!")
        log.info(f"报错url:{product_url}")
        exc_type, exc_value, exc_obj = sys.exc_info()
        log.info(traceback.format_exc(limit=1))
        # log.info(single_product_bs)
        global error_count
        error_count += 1
        error_urls.append(product_url)
    return


def processing(url, price_, moq_):
    # global price
    # global  moq
    global price
    price = price_
    global moq
    global product_url
    moq = moq_
    log.info(f'开始操作:{url}')
    product_url = url
    selenium_product_to_html(url)
    product_detail = product_to_bs4()
    single_product_processing(product_detail)


def product_main():
    setup()

    keyword = cfg("keyword")
    global save_product_file_json_path
    s_path = data_save_format(str(keyword), "products")
    # 最终产品信息->文件保存路径
    global data_abs_dir
    keyword_dir = f"{keyword}"
    data_abs_dir = os.path.join(data_abs_dir, keyword_dir).replace(" ", "_")
    log.info(data_abs_dir)

    if not os.path.exists(data_abs_dir):
        os.mkdir(data_abs_dir)

    save_product_file_json_path = os.path.join(data_abs_dir, s_path)
    log.info(f"文件保存文件{save_product_file_json_path}")

    if cfg("product_detail_auto") == "false":
        file_path = cfg('product_url_list_abs_path')
        if not os.path.exists(file_path):
            with open(file_path, 'w') as f:
                pass
            raise Exception(f"文件不存在:{file_path}")
        product_url_list = read_file_to_list(file_path)
        for product_url in product_url_list:
            processing(product_url, price, moq)
        return

    url_list = get_company_urls_from_file()
    for url in url_list:
        log.info(f"打开公司URL:{url}")
        get_search_for_product_to_html(url, keyword)
        get_search_for_product_from_html()

    if error_count > 0:
        log.warning(f"总共有:{str(error_count)} 数据无法抓取")
        error_urls_str = json.dumps(error_urls, indent=2)
        log.warning(f"错误的url列表: {error_urls_str}")


if __name__ == '__main__':
    product_main()
